---
title: Model Context Protocol (MCP)
---

import AlphaCallout from '/snippets/alpha-lc-callout.mdx';

<AlphaCallout />

:::python
[Model Context Protocol (MCP)](https://modelcontextprotocol.io/introduction) is an open protocol that standardizes how applications provide tools and context to LLMs. LangChain agents can use tools defined on MCP servers using the [`langchain-mcp-adapters`](https://github.com/langchain-ai/langchain-mcp-adapters) library.
:::
:::js
[Model Context Protocol (MCP)](https://modelcontextprotocol.io/introduction) is an open protocol that standardizes how applications provide tools and context to LLMs. LangChain agents can use tools defined on MCP servers using the [`langchain-mcp-adapters`](https://github.com/langchain-ai/langchainjs/tree/main/libs/langchain-mcp-adapters/adapters) library.
:::

![MCP](/oss/images/mcp.png)

## Install

:::python
Install the `langchain-mcp-adapters` library to use MCP tools in LangGraph:

<CodeGroup>
```bash pip
pip install langchain-mcp-adapters
```

```bash uv
uv add langchain-mcp-adapters
```
</CodeGroup>
:::

:::js
Install the `@langchain/mcp-adapters` library to use MCP tools in LangGraph:

<CodeGroup>
```bash npm
npm install @langchain/mcp-adapters
```

```bash pnpm
pnpm add @langchain/mcp-adapters
```

```bash yarn
yarn add @langchain/mcp-adapters
```

```bash bun
bun add @langchain/mcp-adapters
```
</CodeGroup>
:::

## Transport types

MCP supports different transport mechanisms for client-server communication:

- stdio: Client launches server as a subprocess and communicates via standard input/output. Best for local tools and simple setups.
- Streamable HTTP: Server runs as an independent process handling HTTP requests. Supports remote connections and multiple clients.
- Server-Sent Events (SSE): a variant of streamable HTTP optimized for real-time streaming communication.

## Use MCP tools

:::python
`langchain-mcp-adapters` enables agents to use tools defined across one or more MCP server.

```python Accessing multiple MCP servers {highlight={1,4,19,22}} icon="server"
from langchain_mcp_adapters.client import MultiServerMCPClient
from langchain.agents import create_agent

client = MultiServerMCPClient(
    {
        "math": {
            "transport": "stdio",  # Local subprocess communication
            "command": "python",
            # Absolute path to your math_server.py file
            "args": ["/path/to/math_server.py"],
        },
        "weather": {
            "transport": "streamable_http",  # HTTP-based remote server
            # Ensure you start your weather server on port 8000
            "url": "http://localhost:8000/mcp",
        }
    }
)

tools = await client.get_tools()
agent = create_agent(
    "anthropic:claude-3-7-sonnet-latest",
    tools
)
math_response = await agent.ainvoke(
    {"messages": [{"role": "user", "content": "what's (3 + 5) x 12?"}]}
)
weather_response = await agent.ainvoke(
    {"messages": [{"role": "user", "content": "what is the weather in nyc?"}]}
)
```

:::

:::js
`@langchain/mcp-adapters` enables agents to use tools defined across one or more MCP server.

```ts Accessing multiple MCP servers {highlight={1,5,19,22}} icon="server"
import { MultiServerMCPClient } from "@langchain/mcp-adapters";
import { ChatAnthropic } from "@langchain/anthropic";
import { createAgent } from "langchain";

const client = new MultiServerMCPClient({
    math: {
        transport: "stdio",  // Local subprocess communication
        command: "node",
        // Replace with absolute path to your math_server.js file
        args: ["/path/to/math_server.js"],
    },
    weather: {
        transport: "sse",  // Server-Sent Events for streaming
        // Ensure you start your weather server on port 8000
        url: "http://localhost:8000/mcp",
    },
});

const tools = await client.getTools();
const agent = createAgent({
    llm: new ChatAnthropic({ model: "claude-3-7-sonnet-latest" }),
    tools,
});

const mathResponse = await agent.invoke({
    messages: [{ role: "user", content: "what's (3 + 5) x 12?" }],
});

const weatherResponse = await agent.invoke({
    messages: [{ role: "user", content: "what is the weather in nyc?" }],
});
```
:::

<Note>
    `MultiServerMCPClient` is **stateless by default**. Each tool invocation creates a fresh MCP `ClientSession`, executes the tool, and then cleans up.
</Note>

## Custom MCP servers

:::python
To create your own MCP servers, you can use the `mcp` library. This library provides a simple way to define [tools](https://modelcontextprotocol.io/docs/learn/server-concepts#tools-ai-actions) and run them as servers.

<CodeGroup>
```bash pip
pip install mcp
```

```bash uv
uv add mcp
```
</CodeGroup>
:::

:::js
To create your own MCP servers, you can use the `@modelcontextprotocol/sdk` library. This library provides a simple way to define [tools](https://modelcontextprotocol.io/docs/learn/server-concepts#tools-ai-actions) and run them as servers.

<CodeGroup>
```bash npm
npm install @modelcontextprotocol/sdk
```

```bash pnpm
pnpm add @modelcontextprotocol/sdk
```

```bash yarn
yarn add @modelcontextprotocol/sdk
```

```bash bun
bun add @modelcontextprotocol/sdk
```
</CodeGroup>
:::

Use the following reference implementations to test your agent with MCP tool servers.

:::python
```python title="Math server (stdio transport)" icon="floppy-disk"
from mcp.server.fastmcp import FastMCP

mcp = FastMCP("Math")

@mcp.tool()
def add(a: int, b: int) -> int:
    """Add two numbers"""
    return a + b

@mcp.tool()
def multiply(a: int, b: int) -> int:
    """Multiply two numbers"""
    return a * b

if __name__ == "__main__":
    mcp.run(transport="stdio")
```

```python title="Weather server (streamable HTTP transport)" icon="wifi"
from mcp.server.fastmcp import FastMCP

mcp = FastMCP("Weather")

@mcp.tool()
async def get_weather(location: str) -> str:
    """Get weather for location."""
    return "It's always sunny in New York"

if __name__ == "__main__":
    mcp.run(transport="streamable-http")
```
:::

:::js
```typescript title="Math server (stdio transport)" icon="floppy-disk"
import { Server } from "@modelcontextprotocol/sdk/server/index.js";
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
import {
    CallToolRequestSchema,
    ListToolsRequestSchema,
} from "@modelcontextprotocol/sdk/types.js";

const server = new Server(
    {
        name: "math-server",
        version: "0.1.0",
    },
    {
        capabilities: {
        tools: {},
        },
    }
);

server.setRequestHandler(ListToolsRequestSchema, async () => {
    return {
        tools: [
        {
            name: "add",
            description: "Add two numbers",
            inputSchema: {
            type: "object",
            properties: {
                a: {
                type: "number",
                description: "First number",
                },
                b: {
                type: "number",
                description: "Second number",
                },
            },
            required: ["a", "b"],
            },
        },
        {
            name: "multiply",
            description: "Multiply two numbers",
            inputSchema: {
            type: "object",
            properties: {
                a: {
                type: "number",
                description: "First number",
                },
                b: {
                type: "number",
                description: "Second number",
                },
            },
            required: ["a", "b"],
            },
        },
        ],
    };
});

server.setRequestHandler(CallToolRequestSchema, async (request) => {
    switch (request.params.name) {
        case "add": {
        const { a, b } = request.params.arguments as { a: number; b: number };
        return {
            content: [
            {
                type: "text",
                text: String(a + b),
            },
            ],
        };
        }
        case "multiply": {
        const { a, b } = request.params.arguments as { a: number; b: number };
        return {
            content: [
            {
                type: "text",
                text: String(a * b),
            },
            ],
        };
        }
        default:
        throw new Error(`Unknown tool: ${request.params.name}`);
    }
});

async function main() {
    const transport = new StdioServerTransport();
    await server.connect(transport);
    console.error("Math MCP server running on stdio");
}

main();
```

```typescript title="Weather server (SSE transport)" icon="wifi"
import { Server } from "@modelcontextprotocol/sdk/server/index.js";
import { SSEServerTransport } from "@modelcontextprotocol/sdk/server/sse.js";
import {
    CallToolRequestSchema,
    ListToolsRequestSchema,
} from "@modelcontextprotocol/sdk/types.js";
import express from "express";

const app = express();
app.use(express.json());

const server = new Server(
    {
        name: "weather-server",
        version: "0.1.0",
    },
    {
        capabilities: {
        tools: {},
        },
    }
);

server.setRequestHandler(ListToolsRequestSchema, async () => {
    return {
        tools: [
        {
            name: "get_weather",
            description: "Get weather for location",
            inputSchema: {
            type: "object",
            properties: {
                location: {
                type: "string",
                description: "Location to get weather for",
                },
            },
            required: ["location"],
            },
        },
        ],
    };
});

server.setRequestHandler(CallToolRequestSchema, async (request) => {
    switch (request.params.name) {
        case "get_weather": {
        const { location } = request.params.arguments as { location: string };
        return {
            content: [
            {
                type: "text",
                text: `It's always sunny in ${location}`,
            },
            ],
        };
        }
        default:
        throw new Error(`Unknown tool: ${request.params.name}`);
    }
});

app.post("/mcp", async (req, res) => {
    const transport = new SSEServerTransport("/mcp", res);
    await server.connect(transport);
});

const PORT = process.env.PORT || 8000;
app.listen(PORT, () => {
    console.log(`Weather MCP server running on port ${PORT}`);
});
```
:::

:::python
## Expose LangChain tools via MCP

You can also expose existing LangChain tools through an MCP server using the `to_fastmcp` function. This allows you to make your LangChain tools available to any MCP client.

```python Make LangChain tools available via MCP icon="tool"
from langchain_core.tools import tool
from langchain_mcp_adapters.tools import to_fastmcp
from mcp.server.fastmcp import FastMCP


@tool
def add(a: int, b: int) -> int:
    """Add two numbers"""
    return a + b

@tool
def get_user_info(user_id: str) -> str:
    """Get information about a user"""
    return f"User {user_id} is active"


# Convert LangChain tools to FastMCP
fastmcp_tools = [to_fastmcp(tool) for tool in (add, get_user_info)]

# Create server using converted tools
mcp = FastMCP("LangChain Tools", tools=fastmcp_tools)
mcp.run(transport="stdio")
```
:::

## Stateful tool usage

For stateful servers that maintain context between tool calls, use `client.session()` to create a persistent `ClientSession`.

:::python
```python Using MCP ClientSession for stateful tool usage
from langchain_mcp_adapters.tools import load_mcp_tools

client = MultiServerMCPClient({...})
async with client.session("math") as session:
    tools = await load_mcp_tools(session)
```
:::

:::js
```typescript Using MCP ClientSession for stateful tool usage
import { loadMCPTools } from "@langchain/mcp-adapters/tools.js";

const client = new MultiServerMCPClient({...});
const session = await client.session("math");
const tools = await loadMCPTools(session);
```
:::

## Additional resources

* [MCP documentation](https://modelcontextprotocol.io/introduction)
* [MCP Transport documentation](https://modelcontextprotocol.io/docs/concepts/transports)
:::python
* [`langchain-mcp-adapters`](https://github.com/langchain-ai/langchain-mcp-adapters)
:::
:::js
* [`langchain-mcp-adapters`](https://github.com/langchain-ai/langchainjs/tree/main/libs/langchain-mcp-adapters/)
:::
